﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using DomainModel;
using Services.Abstract;

namespace Web
{
    public partial class Groups : BasePage
    {
        public IGroupService GroupService { get; set; }
        public IUserService UserService { get; set; }
        public IPermissionService PermissionService { get; set; }
        public IEmailService EmailService { get; set; }

        protected Group SelectedGroup;

        protected new void Page_Load(object sender, EventArgs e)
        {
            SelectMenuItem("NavGroups");

            BindListViewGroups();

            if (Request.QueryString["GroupId"] != null)
            {
                try
                {
                    long groupId = long.Parse(Request.QueryString["GroupId"]);
                    SelectedGroup = GroupService.GetById(groupId);
                    StudentsSection.Visible = true;
                    BindListViewStudents();
                }
                catch (Exception)
                {
                    Response.Redirect("/Groups.aspx");
                }
            }
        }

        private void BindListViewGroups()
        {
            var groupsList = GroupService.GetAll().OrderBy(g => g.Name).ToList();

            var ds = new List<object>();

            foreach (var group in groupsList)
            {
                ds.Add(new
                {
                    Id = group.Id,
                    Name = group.Name,
                    CuratorFio = group.Curator == null ? "не выбрано" : group.Curator.UserProfile.Fio,
                    PraepostorFio = group.Praepostor == null ? "не выбрано" : group.Praepostor.UserProfile.Fio,
                });
            }

            ListViewGroups.DataSource = ds;
            ListViewGroups.DataBind();
        }

        private void ShowEditGroupForm(long id = 0, string name = null, long curatorId = 0, bool showDeleteBtn = false)
        {
            if (id != 0)
            {
                if (ViewState["groupId"] == null)
                {
                    ViewState.Add("groupId", id);
                }
                else
                {
                    ViewState["groupId"] = id;
                }
            }
            else
            {
                if (ViewState["groupId"] != null)
                {
                    ViewState.Remove("groupId");
                }
            }

            BindDdlTeachers();

            TbGroupName.Text = name ?? "";
            if (curatorId > 0)
            {
                DdlTeachers.Items.FindByValue(curatorId.ToString()).Selected = true;
            }

            ButtonDeleteGroup.Visible = showDeleteBtn;

            EditGroupForm.Visible = true;
        }

        private void HideEditGroupForm()
        {
            if (ViewState["groupId"] != null)
            {
                ViewState.Remove("groupId");
            }

            EditGroupForm.Visible = false;
        }

        private void BindListViewStudents()
        {
            var studentsList = UserService.GetUsers(SelectedGroup, false).OrderBy(s => s.UserProfile.Fio);

            var ds = new List<object>();

            foreach (var student in studentsList)
            {
                bool isPaepostor = SelectedGroup.Praepostor != null && student.Id == SelectedGroup.Praepostor.Id;
                bool canApproveUsers = PermissionService.CanApproveUser(student);
                bool canChangePraeposotr = PermissionService.CanChangePraepostor(SelectedGroup);

                ds.Add(new
                {
                    Id = student.Id,
                    Fio = student.UserProfile.Fio,
                    Login = student.Login,
                    AvatarUrl = student.UserProfile.PhotoUrl,
                    IsStarostaInfoVisible = isPaepostor,
                    MakeAsPraepostorVisible = !isPaepostor && student.Approved && canChangePraeposotr,
                    ToApproveVisible = !student.Approved && canApproveUsers,
                });
            }

            ListViewStudents.DataSource = ds;
            ListViewStudents.DataBind();
        }

        protected void BtnAddGroup_OnClick(object sender, EventArgs e)
        {
            ShowEditGroupForm();
        }

        protected void BtnChangeGroup_OnClick(object sender, EventArgs e)
        {
            long groupId;
            try
            {
                var listView = ((LinkButton)sender).Parent as ListViewDataItem;

                var dataKey = ListViewGroups.DataKeys[listView.DataItemIndex];

                groupId = long.Parse(dataKey.Value.ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            var group = GroupService.GetById(groupId);
            if (group == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти группу.");
                return;
            }

            BindDdlTeachers();

            ShowEditGroupForm(groupId, group.Name, group.Curator == null ? 0 : group.Curator.Id, true);
        }

        private void BindDdlTeachers()
        {
            var teachersList = UserService.GetUsers(Role.Teacher);

            var ds = new List<object> { new { Id = (long)0, Fio = "" } };

            foreach (var teacher in teachersList)
            {
                ds.Add(new
                {
                    Id = teacher.Id,
                    Fio = teacher.UserProfile.Fio,
                });
            }

            DdlTeachers.DataSource = ds;
            DdlTeachers.DataValueField = "Id";
            DdlTeachers.DataTextField = "Fio";
            DdlTeachers.DataBind();
        }

        protected void ButtonSaveGroup_OnClick(object sender, EventArgs e)
        {
            string name = TbGroupName.Text;

            long curatorId;
            try
            {
                curatorId = long.Parse(DdlTeachers.SelectedValue);
            }
            catch (FormatException)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            User curator;
            if (curatorId == 0)
            {
                curator = null;
            }
            else
            {
                curator = UserService.GetById(curatorId);
                if (curator == null)
                {
                    ShowSysMsg("Ошибка базы данных. Невозможно найти преподавателя.");
                    return;
                }
            }

            Group group;
            if (ViewState["groupId"] == null)
            {
                group = new Group(name) { Curator = curator, };
            }
            else
            {
                try
                {
                    long groupId = long.Parse(ViewState["groupId"].ToString());
                    group = GroupService.GetById(groupId);

                    if (group == null)
                    {
                        ShowSysMsg("Ошибка базы данных. Невозможно найти группу.");
                        return;
                    }

                    group.Name = name;
                    group.Curator = curator;
                }
                catch (Exception)
                {
                    ShowSysMsg("Возникла непредвиденная ошибка.");
                    return;
                }
            }

            try
            {
                GroupService.SaveOrUpdate(group);

                HideEditGroupForm();
                BindListViewGroups();
                BindListViewStudents();
            }
            catch (Exception ex)
            {
                ShowFormError(EditGroupFormError.ClientID, ex.Message);
            }
        }

        protected void ButtonDeleteGroup_OnClick(object sender, EventArgs e)
        {
            if (ViewState["groupId"] == null)
            {
                return;
            }

            long groupId;
            try
            {
                groupId = long.Parse(ViewState["groupId"].ToString());
            }
            catch (FormatException)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            Group group = GroupService.GetById(groupId);
            if (group == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти преподавателя.");
                return;
            }

            try
            {
                GroupService.Delete(group);

                HideEditGroupForm();
                StudentsSection.Visible = false;
                BindListViewGroups();
            }
            catch (Exception ex)
            {
                ShowFormError(EditGroupFormError.ClientID, ex.Message);
            }
        }

        protected void ButtonCancelGroup_OnClick(object sender, EventArgs e)
        {
            HideEditGroupForm();
        }

        protected void BtnMakeAsPraepostor_OnClick(object sender, EventArgs e)
        {
            long studentId;
            try
            {
                var listView = ((LinkButton)sender).Parent.Parent as ListViewDataItem;
                var dataKey = ListViewStudents.DataKeys[listView.DataItemIndex];
                studentId = long.Parse(dataKey.Value.ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            var student = UserService.GetById(studentId);

            if (student == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти студента.");
                return;
            }

            try
            {
                var oldPraepostor = SelectedGroup.Praepostor;
                SelectedGroup.Praepostor = student;

                GroupService.SaveOrUpdate(SelectedGroup);

                string msgBody;
                if (oldPraepostor != null)
                {
                    msgBody = "<h1>Уважаемый " + oldPraepostor.UserProfile.Fio + "</h1>" +
                                    "К сожалению, Вы были сняты с должности старосты группы " + oldPraepostor.Group.Name + ".";

                    EmailService.Send(oldPraepostor.Email, "Вы сняты с должности старосты", msgBody);
                }

                msgBody = "<h1>Уважаемый " + student.UserProfile.Fio + "</h1>" +
                            "Поздравляем Вас! Вы были назначены на должность старосты группы " + student.Group.Name + ". " +
                            "Желаем Вам успешно справляться с Вашими новыми обязанностями.";

                EmailService.Send(student.Email, "Вы назначены на должность старосты", msgBody);

                BindListViewGroups();
                BindListViewStudents();
            }
            catch (Exception ex)
            {
                ShowSysMsg(ex.Message);
            }
        }

        protected void BtnApprove_OnClick(object sender, EventArgs e)
        {
            long studentId;
            try
            {
                var listView = ((LinkButton)sender).Parent.Parent as ListViewDataItem;
                var dataKey = ListViewStudents.DataKeys[listView.DataItemIndex];
                studentId = long.Parse(dataKey.Value.ToString());
            }
            catch (Exception)
            {
                ShowSysMsg("Возникла непредвиденная ошибка.");
                return;
            }

            var student = UserService.GetById(studentId);

            if (student == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти студента.");
                return;
            }

            try
            {
                student.Approved = true;

                UserService.SaveOrUpdate(student);

                string msgBody = "<h1>Уважаемый " + student.UserProfile.Fio + "</h1>" +
                                 "Ваша регистрация на ресурсе StudyControl подтверждена.";

                EmailService.Send(student.Email, "Регистрация на ресурсе StudyControl подтверждена", msgBody);

                BindListViewStudents();
            }
            catch (Exception ex)
            {
                ShowSysMsg(ex.Message);
            }
        }
    }
}